<template>
  <div class="mine">
    <z-head text="测试表单组件" leftSvg=""></z-head>
    <Form ref="formRef">
      <z-input v-model="form.username" name="username" label="用户名" :rules="[{ required: true, message: '请输入内容', validator: reg('loginName') }]" required> </z-input>
      <z-input v-model="form.password" name="password" label="密码" :type="showText ? 'text' : 'password'" :rules="[{ required: true, message: '请输入内容', validator: reg('loginPwd') }]" required>
        <template #right-icon> <z-svg :name="showText ? 'yanjing' : 'yanjing1'" @click="showText = !showText"></z-svg> </template>
      </z-input>
      <z-input v-model="form.height" name="password" label="身高" :rules="[{ required: true, message: '请输入内容', validator: reg('intNum') }]" :maxlength="3" required>
        <template #extra> cm </template>
      </z-input>
      <z-input v-model="form.textarea" name="textarea" label="建议" :rules="[{ validator: reg('textName') }]" type="textarea" :maxlength="100"> </z-input>
      <!-- 如果两个时间之间没有有比较，confirm函数不需要写！！ -->
      <z-time v-model="form.time1" name="time1" label="开始时间" type="datetime" required @confirm="confirm5"> </z-time>
      <z-time v-model="form.time2" name="time2" label="结束时间" type="datetime" required @confirm="confirm6"> </z-time>
      <z-select
        v-model="form.select1"
        name="select1"
        label="select下拉框1"
        required
        :label-width="pxToRem(120)"
        :columns="columns1.list"
        :default-index="1"
        @clear="
          () => {
            form.select2.text = ''
            form.select2.code = ''
          }
        "
      ></z-select>
      <z-select v-model="form.select2" name="select2" label="select下拉框2" required :readonly="!form.select1.code" hasFather :label-width="pxToRem(120)" :columns="columns2.list"></z-select>
      <z-select v-model="form.select3" name="select3" label="select级联" :label-width="pxToRem(120)" :columns="columns3.list"></z-select>
      <z-select v-model="form.select4" name="select4" label="select级联回选" :label-width="pxToRem(120)" :columns="columns4.list"></z-select>
      <z-cascader v-model="form.cascader1" name="cascader1" label="cascader级联" :options="cascaderOptions1"></z-cascader>
      <z-cascader v-model="form.cascader2" name="cascader2" label="cascader级联回选" required :options="cascaderOptions2"></z-cascader>
      <z-calendar v-model="form.calendar1" name="calendar1" label="日历单选" type="single" :default-date="form.calendar1DefaultDate"></z-calendar>
      <z-calendar v-model="form.calendar2" name="calendar2" label="日历范围" type="range" required :default-date="form.calendar2DefaultDate"></z-calendar>
      <z-checkbox v-model="form.checkboxList" name="checkbox" label="复选框回选" :list="checkboxList"></z-checkbox>
      <z-radio v-model="form.radio" name="checkbox" label="复选框回选" :list="radioList"></z-radio>
      <z-uploader v-model="form.fileList" name="fileList" label="文件上传" :before-read="beforeRead" :after-read="afterRead"></z-uploader>
    </Form>

    <div class="btns">
      <Button round block type="warning" size="small" @click="clear"> 清空 </Button>
      <Button round block type="primary" size="small" @click="submit"> 提交 </Button>
    </div>
  </div>
</template>

<script setup>
import { reactive, ref } from 'vue'
import { Form, Button, Toast, Notify } from 'vant'
import $day from 'dayjs'
import reg from '@/utils/reg'
import { pxToRem, getType, checkFile } from '@/utils'

const formRef = ref()
// 表单数据
const form = reactive({
  username: 'zls',
  password: 'Qwer1234@',
  height: '173',
  textarea: '',
  time1: null,
  time2: null,
  select1: { text: '李四', code: '4' },
  select2: { text: '', code: '' },
  select3: { text: '', code: null },
  select4: { text: '', code: null },
  cascader1: { text: '', code: null },
  cascader2: { text: '', code: null },
  calendar1: '2022-05-25',
  calendar1DefaultDate: new Date('2022-05-25'),
  calendar2: '2022-05-26,2022-09-10',
  calendar2DefaultDate: [new Date('2022-05-26'), new Date('2022-09-10')],
  checkboxList: ['2'],
  radio: '',
  fileList: null
})
const showText = ref(false) // 控制密码的显示与隐藏

// 下拉框配置项
const columns1 = reactive({
  list: [
    { text: '张三', code: '3' },
    { text: '李四', code: '4' },
    { text: '王五', code: '5' }
  ]
})
const columns2 = reactive({
  list: [
    { text: '马六', code: '7' },
    { text: '秦七', code: '8' },
    { text: '陈八', code: '9' }
  ]
})
const columns3 = reactive({
  list: [
    {
      text: '',
      code: '',
      children: [
        {
          text: '浙江',
          code: 1,
          children: [
            {
              text: '杭州',
              code: 11,
              children: [
                { text: '西湖区', code: 111 },
                { text: '余杭区', code: 112 }
              ]
            },
            {
              text: '温州',
              code: 12,
              children: [{ text: '鹿城区', code: 122 }]
            }
          ]
        },
        {
          text: '福建',
          code: 2,
          children: [
            {
              text: '福州',
              code: 22,
              children: [{ text: '鼓楼区', code: 222 }]
            }
          ]
        }
      ]
    }
  ]
})
const columns4 = reactive({
  list: [
    {
      text: '',
      code: '',
      children: [
        {
          text: '浙江',
          code: 1,
          children: [
            {
              text: '杭州',
              code: 11,
              children: [
                { text: '西湖区', code: 111, disabled: true },
                { text: '余杭区', code: 112 }
              ]
            },
            {
              text: '温州',
              code: 12,
              children: [
                { text: '鹿城区', code: 122 },
                { text: '瓯海区', code: 123 }
              ]
            }
          ]
        },
        {
          text: '福建',
          code: 2,
          children: [
            {
              text: '福州',
              code: 22,
              children: [
                { text: '鼓楼区', code: 222 },
                { text: '台江区', code: 223 }
              ]
            },
            {
              text: '厦门',
              code: 23,
              children: [
                { text: '思明区', code: 233 },
                { text: '海沧区', code: 234 }
              ]
            }
          ]
        }
      ]
    }
  ],
  defaultIndex: ''
})
// select级联选择器回选
backSelect(columns4.list)
form.select4.text = form.select4.text.slice(0, -1)
function backSelect(arr) {
  const codeArr = [2, 23, 233] // 后台给的回选值
  arr.forEach(v => {
    if (v.children) {
      v.children.forEach((item, i) => {
        if (codeArr.indexOf(item.code) !== -1) {
          v.defaultIndex = i
          ;(form.select4.code || (form.select4.code = [])).push(item.code)
          form.select4.text += `${item.text},`
        }
      })
      backSelect(v.children)
    }
  })
}

// 时间选择配置
function confirm5(data) {
  if ($day(data).valueOf() > $day(form.time2).valueOf()) {
    Toast('开始时间不能大于结束时间')
    form.time1 = null
    return
  }
  form.time1 = $day(data).format('YYYY-MM-DD HH:mm')
}
function confirm6(data) {
  if ($day(data).valueOf() < $day(form.time1).valueOf()) {
    Toast('结束时间不能小于开始时间')
    form.time2 = null
    return
  }
  form.time2 = $day(data).format('YYYY-MM-DD HH:mm')
}

// cascader级联选择
const cascaderOptions1 = reactive([
  {
    text: '浙江省',
    value: '330000',
    children: [{ text: '杭州市', value: '330100' }]
  },
  {
    text: '江苏省',
    value: '320000',
    children: [{ text: '南京市', value: '320100' }]
  }
])
const cascaderOptions2 = reactive([
  {
    text: '安徽省',
    value: '330000',
    children: [
      { text: '合肥市', value: '330100' },
      { text: '滁州市', value: '330200' }
    ]
  },
  {
    text: '江苏省',
    value: '320000',
    children: [
      { text: '南京市', value: '320100' },
      { text: '苏州市', value: '320200' }
    ]
  }
])
// cascader级联选择器回选
const codeArr = ['320000', '320200'] // 后台给的code码
form.cascader2.code = codeArr
backCascader(cascaderOptions2, codeArr)
form.cascader2.text = form.cascader2.text.slice(0, -1)
function backCascader(arr, codeArr) {
  arr.forEach(v => {
    if (codeArr.indexOf(v.value) !== -1) {
      form.cascader2.text += `${v.text},`
    }
    if (v.children) backCascader(v.children, codeArr)
  })
}

// 复选框列表数据
const checkboxList = reactive([
  { text: '复选框1', code: '1' },
  { text: '复选框2', code: '2' },
  { text: '复选框3', code: '3' }
])
// 单选框数据
const radioList = reactive([
  { text: '单选框1', code: '11' },
  { text: '单选框2', code: '22' },
  { text: '单选框3', code: '33' }
])

// 文件读取前的回调函数(常用于限制文件的上传类型及文件大小等)
function beforeRead(file, detail) {
  if (checkFile(file.name) === 'image' || checkFile(file.name) === 'word' || checkFile(file.name) === 'excel') {
    console.log('---上传前的文件---', file, detail)
    return true
  }
  Toast('仅支持 图片/word/excel 的常见格式')
  return false
}
// 上传成功(调用后台文件服务接口，将文件上传至文件服务，更新文件列表)
function afterRead(file, detail) {
  console.log('---上传成功的文件---', file, detail)
  file.status = 'uploading'
  file.message = '上传中...'
  setTimeout(() => {
    const name = file.file.name
    let obj = {}
    switch (checkFile(name)) {
      case 'image':
        obj = { url: 'https://img0.baidu.com/it/u=3976458258,1573032133&fm=253&fmt=auto&app=138&f=PNG?w=977&h=370', isImage: true, type: 'image', name }
        break
      case 'word':
        obj = { url: '', type: 'word', name }
        break
      case 'excel':
        obj = { url: '', type: 'excel', name }
        break
      default:
        break
    }
    ;(form.fileList || (form.fileList = [])).push(obj)
    file.status = 'done'
    file.message = '上传成功'
    Notify({ type: 'success', message: '上传成功' })
  }, 1000)
}

// 清空表单
function clear() {
  const objType = { number: '', string: '', undefined: undefined, null: null, object: { text: '', code: null }, array: null }
  Object.entries(form).forEach(([key, value]) => {
    const type = getType(value)
    form[key] = typeof value?.code === 'string' ? { text: '', code: '' } : objType[type]
  })
  form.calendar1DefaultDate = new Date()
  form.calendar2DefaultDate = [new Date(), new Date()]
  console.log('--清空表单--', form)
}

// 提交表单
function submit() {
  formRef.value
    .validate()
    .then(() => {
      console.log('--提交成功--', form)
    })
    .catch(err => {
      console.log('--提交失敗--', err)
    })
}
</script>

<style lang="scss" scoped>
.mine {
  height: calc(100% - 50px);
  display: flex;
  flex-direction: column;
  .van-form {
    flex: 1;
    overflow-y: auto;
  }
  .btns {
    display: flex;
    padding: 0 15px;
    margin: 15px 0;
  }
}
</style>
